package com.lw.common.network

import android.util.Log
import com.aleyn.cache.CacheManager
import com.aleyn.cache.NetCacheInterceptor
import com.lw.common.adapter.FlowAdapterFactory
import com.lw.common.base.AppContext
import com.lw.common.utils.MMKVUtils
import okhttp3.ConnectionPool
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import okio.Buffer
import org.json.JSONException
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.util.concurrent.TimeUnit

object RetrofitClient {

    fun <T> create(service: Class<T>?): T =
        Retrofit.Builder()
            .client(getOkHttpClient())
            .addCallAdapterFactory(FlowAdapterFactory.create(true))
            .addConverterFactory(GsonConverterFactory.create())
            .baseUrl(UrlUtils.getBaseUrl())
            .build()
            .create(service!!) ?: throw RuntimeException("Api service is null!")

    private fun getOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder()
            .connectTimeout(15L, TimeUnit.SECONDS)
            .writeTimeout(20L, TimeUnit.SECONDS)
            .readTimeout(20L, TimeUnit.SECONDS)
            .connectionPool(ConnectionPool(8, 15, TimeUnit.SECONDS))
            .addInterceptor(HeaderInterceptor())
            .addInterceptor(
                NetCacheInterceptor(
                    CacheManager(
                        AppContext.cacheDir, maxSize = 50 * 1024 * 1024,
                    )
                )
            )
            .addInterceptor(LoggingInterceptor())
            .build()
    }

    /**
     * 添加请求头需要携带的参数
     */
    class HeaderInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            val keyToken = MMKVUtils.getToken()
            val originalRequest: Request = chain.request()
            return if (keyToken == "") {
                chain.proceed(originalRequest)
            } else {
                val updateRequest =
                    originalRequest.newBuilder().header("token", keyToken).build()
                chain.proceed(updateRequest)
            }
        }
    }

    /**
     * 日志拦截器
     */
    class LoggingInterceptor : Interceptor {
        @Throws(IOException::class)
        override fun intercept(chain: Interceptor.Chain): Response {
            //这个chain里面包含了request和response，所以你要什么都可以从这里拿
            val request: Request = chain.request()
            val t1 = System.nanoTime() //请求发起的时间
            val method = request.method
            val jsonObject = JSONObject()
            if ("POST" == method || "PUT" == method) {
                if (request.body is FormBody) {
                    val body = request.body as FormBody?
                    if (body != null) {
                        for (i in 0 until body.size) {
                            try {
                                jsonObject.put(body.name(i), body.encodedValue(i))
                            } catch (e: JSONException) {
                                e.printStackTrace()
                            }
                        }
                    }
                    Log.i(
                        "request", String.format(
                            "Retrofit发送请求 %s on %s  %nRequestParams:%s%nMethod:%s",
                            request.url, chain.connection(), jsonObject, request.method
                        )
                    )
                } else {
                    val buffer = Buffer()
                    val requestBody = request.body
                    if (requestBody != null) {
                        request.body!!.writeTo(buffer)
                        val body = buffer.readUtf8()
                        Log.i(
                            "request", String.format(
                                "Retrofit发送请求 %s on %s  %nRequestParams:%s%nMethod:%s",
                                request.url, chain.connection(), body, request.method
                            )
                        )
                    }
                }
            } else {
                Log.i(
                    "request", String.format(
                        "Retrofit发送请求 %s on %s%nMethod:%s",
                        request.url, chain.connection(), request.method
                    )
                )
            }
            val response: Response = chain.proceed(request)
            val t2 = System.nanoTime() //收到响应的时间
            val responseBody = response.peekBody((1024 * 1024).toLong())
            Log.i(
                "request", String.format(
                    "Retrofit接收响应: %s %n返回json:【%s】 %n耗时：%.1fms",
                    response.request.url,
                    responseBody.string(),
                    (t2 - t1) / 1e6
                )
            )
            return response
        }
    }

//    fun <T> create(service: Class<T>?): T =
//        retrofit.create(service!!) ?: throw RuntimeException("Api service is null!")

}